package com.xdoc.client.util;

import com.xdoc.client.ApiInvoker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
 * IO工具类
 * @author coffish
 */
public class IOUtils {
    private final static Log logger = LogFactory.getLog(IOUtils.class);
    public static void pipe(InputStream in, OutputStream out) throws IOException {
        try {
            int len;
            byte[] buf = new byte[4096];
            while (true) {
                len = in.read(buf);
                if (len > 0) {
                    out.write(buf, 0, len);
                } else {
                    break;
                }
            }
            out.flush();
        } finally {
            in.close();
            out.close();
        }
    }
    public static boolean isFile(String url) {
        int pos = url.indexOf(':');
        return pos < 0
                || pos == 1
                || (pos == 2 && url.charAt(0) == '/');
    }
    /**
     * URL结果转换为datauri
     * @param url http/ftp/file
     * @return
     * @throws IOException
     */
    public static String toDataURI(String url) throws IOException {
        return toDataURI(url, null);
    }
    /**
     * URL结果转换为datauri
     * @param url http/ftp/file
     * @param format 文件格式或mime-type
     * @return
     * @throws IOException
     */
    public static String toDataURI(String url, String format) throws IOException {
        if (url.length() > 0) {
            logger.debug("URL转DataURI:" + url);
            InputStream in = null;
            if (isFile(url)) {
                if (format == null) {
                    format = getFileFormat(url);
                }
                in = new FileInputStream(url);
            } else {
                URLConnection conn = new URL(encodeURI(url)).openConnection();
                in = conn.getInputStream();
                if (format == null) {
                    format = conn.getContentType();
                }
            }
            return toDataURI(in, format);
        } else {
            return "";
        }
    }
    private static String encodeURI(String str) {
        char[] cs = str.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < cs.length; i++) {
            if (cs[i] >= 'a' && cs[i] <='z'
                    || cs[i] >= 'A' && cs[i] <='Z'
                    || cs[i] >= '0' && cs[i] <='9'
                    || "-_.!~*'();/?:@&=+$,#%".indexOf(cs[i]) >= 0) {
                sb.append(cs[i]);
            } else if (cs[i] == ' ') {
                sb.append("%20");
            } else {
                try {
                    sb.append(URLEncoder.encode(String.valueOf(cs[i]), "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    sb.append(cs[i]);
                }
            }
        }
        return sb.toString();
    }
    /**
     * URL转换为datauri
     * @param url
     * @return
     * @throws IOException
     */
    public static String toDataURI(URL url) throws IOException {
        logger.debug("URL转DataURI:" + url);
        URLConnection conn = url.openConnection();
        return toDataURI(conn.getInputStream(), conn.getContentType());
    }
    /**
     * 数据流转换为datauri
     * @param in
     * @return
     * @throws IOException
     */
    public static String toDataURI(InputStream in) throws IOException {
        return toDataURI(in, null);
    }
    /**
     * 数据流转换为datauri
     * @param in
     * @param format 文件格式或mime-type
     * @return
     * @throws IOException
     */
    public static String toDataURI(InputStream in, String format) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        pipe(in, out);
        if (format != null) {
            if (format.indexOf('/') < 0) {
                if (format.equals("jpg")) {
                    format = "jpeg";
                } else if (format.equals("htm")) {
                    format = "html";
                }
                if (format.equals("png") || format.equals("jpeg") || format.equals("gif")) {
                    format = "image/" + format;
                } else if (format.equals("html") || format.equals("xml")) {
                    format = "text/" + format;
                } else {
                    format = "application/" + format;
                }
            }
        } else {
            format = "application/octet-stream";
        }
        StringBuffer sb = new StringBuffer();
        sb.append("data:").append(format).append(";base64,");
        sb.append(Base64.encode(out.toByteArray()));
        return sb.toString();
    }
    public static String getFileFormat(String fileName) {
        String format = "";
        int pos = fileName.lastIndexOf(".");
        if (pos > 0) {
            format = fileName.substring(pos + 1).toLowerCase();
        }
        return format;
    }

    public static String urlEncode(String str) throws IOException {
        str = URLEncoder.encode(str, "UTF-8");
        if (str.indexOf('+') >= 0) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < str.length(); i++) {
                if (str.charAt(i) == '+') {
                    sb.append("%20");
                } else {
                    sb.append(str.charAt(i));
                }
            }
            str = sb.toString();
        }
        return str;
    }

    public static String toString(InputStream in) throws IOException {
        StringWriter writer = new StringWriter();
        String str;
        BufferedReader bReader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        boolean first = true;
        while ((str = bReader.readLine()) != null) {
            if (!first) {
                writer.write("\r\n");
            }
            writer.write(str);
            first = false;
        }
        writer.flush();
        writer.close();
        return writer.toString();
    }
}
